package ju.demo.simple;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.VisitorSupport;
import org.dom4j.io.SAXReader;

public class XMLSimpleOperations extends VisitorSupport{

	
	/***
	 * read XML document from fileName
	 * @param fileName
	 * @return
	 * @throws DocumentException
	 */
	public Document read(String fileName) throws DocumentException {
		SAXReader reader = new SAXReader();
		Document docement = reader.read(new File(fileName));
		return docement;
	}
	
	/***
	 * get root element of XML document
	 * @param doc
	 * @return
	 */
	public Element getRootElement(Document doc) {
		return doc.getRootElement();
	}
	
	/**
	 * traverse XML document by iteration 
	 * @param root
	 */
	public void traverseXMLDocumentByIteration(Element root) {
		//iterate all child nodes
		for(Iterator i=root.elementIterator(); i.hasNext(); ) {
			Element element = (Element)i.next();
			//do something
		}
		//iterate all nodes whose tag name is 'foo'
		for(Iterator i=root.elementIterator("foo"); i.hasNext();) {
			Element foo = (Element)i.next();
			//do something
		}
		//iterate element
		for(Iterator i = root.attributeIterator(); i.hasNext(); ) {
			Attribute attribute = (Attribute) i.next();
			//do something
		}
	}
	
	/***
	 * traverse XML document by recursion
	 */
	public void treeWalk(Document doc) {
		treeWalk(getRootElement(doc));
	}

	public void treeWalk(Element element) {
		for(int i=0, size=element.nodeCount(); i<size; i++) {
			Node node = element.node(i);
			if(node instanceof Element) {
				treeWalk((Element) node);
			} else {
				//do something
			}
		}
	}
	
	/**
	 * traverse XML document by visitor GoF
	 * invoke by code: root.accept(this)
	 */
	public void visit(Element element) {
		System.out.println(element.getName());
	} 
	
	public void visit(Attribute attr) {
		System.out.println(attr.getName());
	}
	
	/**
	 * transfer XML to String
	 * @param doc
	 * @return
	 */
	public String transferXMLToString(Document doc) {
		return doc.asXML();
	}
	
	/**
	 * transfer String to XML
	 * @param string
	 * @return
	 * @throws DocumentException
	 */
	public Document transferStringToXML(String string) throws DocumentException {
		return DocumentHelper.parseText(string);
	}
	
	/**
	 * create XML document
	 * @return
	 */
	public Document createDocument() {
		Document document = DocumentHelper.createDocument();
		Element root = document.addElement("root");
		Element author1 =root.addElement("author").addAttribute("name", "James").addAttribute("location", "UK").addText("Kong Lingjun");
		return document;
	}
	
	public void write(Document document) throws IOException {
		FileWriter out = new FileWriter("foo.xml");
		document.write(out);
	}
}
